﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using TjZheng.WeiXin.DataEntity;
using TjZheng.Framework;
using System.Net.Security;
using TjZheng.Web.Helper;
using System.Security.Cryptography.X509Certificates;

namespace TjZheng.WeiXin.SDK.Pay
{
    public static class WxPayApi
    {
        /// <summary>
        /// MD5加密
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string EncodeMD5(string str)
        {
            //MD5加密
            var md5 = MD5.Create();
            var bs = md5.ComputeHash(Encoding.UTF8.GetBytes(str));
            var sb = new StringBuilder();
            foreach (byte b in bs)
            {
                sb.Append(b.ToString("x2"));
            }
            //所有字符转为大写
            return sb.ToString();
        }

        /// <summary>
        /// 生成随机串
        /// </summary>
        /// <returns></returns>
        public static string GenerateNonceStr()
        {
            return Guid.NewGuid().ToString().Replace("-", "");
        }

        /// <summary>
        /// 根据当前系统时间加随机序列来生成订单号
        /// </summary>
        /// <param name="mkey"></param>
        /// <returns></returns>
        public static string GenerateOutTradeNo(string mchId)
        {
            var ran = new Random();
            return string.Format("{0}{1}{2}", mchId, DateTime.Now.ToString("yyyyMMddHHmmss"), ran.Next(999));
        }

        /// <summary>
        /// 生成时间戳，标准北京时间，时区为东八区，自1970年1月1日 0点0分0秒以来的秒数
        /// </summary>
        /// <returns></returns>
        public static string GenerateTimeStamp()
        {
            TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return Convert.ToInt64(ts.TotalSeconds).ToString();
        }

        public static WxPayPackage CreateWxPayApiRequest(this string url, WxPayPackage objIntputWxPayPackage, MerchantInfo objMerchantInfo, string method = "POST", bool isUseCert = false, int timeout = 6000)
        {
            if (objIntputWxPayPackage == null)
            {
                throw new ArgumentNullException("objIntputWxPayPackage");
            }
            if (objMerchantInfo == null)
            {
                throw new ArgumentNullException("objMerchantInfo");
            }


            //设置最大连接数
            ServicePointManager.DefaultConnectionLimit = 200;
            //设置https验证方式
            if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
            {
                ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback((sender, certificate, chain, errors) => true);
            }

            HttpWebRequest objHttpWebRequest = url.CreateHttpRequest();
            objHttpWebRequest.Timeout = timeout;
            objHttpWebRequest.Method = method;

            //是否使用证书
            if (isUseCert)
            {
                if (objMerchantInfo.SslcertPath.IsNull() || objMerchantInfo.SslcertPassword.IsNull())
                {
                    throw new WxPayException("发起微信请求时所需要的证书路径和证书密码为空！");
                }
                string physicalApplicationPath = SystemWebAsset.Request.PhysicalApplicationPath;
                X509Certificate2 objX509Certificate2 = new X509Certificate2(physicalApplicationPath + objMerchantInfo.SslcertPath, objMerchantInfo.SslcertPassword);
                objHttpWebRequest.ClientCertificates.Add(objX509Certificate2);
            }

            if (objMerchantInfo.ProxyUrl.IsNoNull())
            {
                //设置代理服务器
                WebProxy objWebProxy = new WebProxy();                          //定义一个网关对象
                objWebProxy.Address = new Uri(objMerchantInfo.ProxyUrl);              //网关服务器端口:端口
                objHttpWebRequest.Proxy = objWebProxy;
            }

            //设置POST的数据类型和长度
            objHttpWebRequest.ContentType = "text/xml";

            string xml = objIntputWxPayPackage.ConvertToXml();
            byte[] data = Encoding.UTF8.GetBytes(xml);
            objHttpWebRequest.ContentLength = data.Length;

            //往服务器写入数据
            var reqStream = objHttpWebRequest.GetRequestStream();
            reqStream.Write(data, 0, data.Length);
            reqStream.Close();

            string response = objHttpWebRequest.GetHttpResponse(Encoding.UTF8);

            return WxPayPackage.ParseFromXml(response);
        }
    }
}
